/*
 * Timer.h
 *
 *  Created on: 2021年4月5日
 *      Author: san
 */


/* 处理逻辑是这样的~
因为
(1) 优先队列不支持随机访问
(2) 即使支持，随机删除某节点后破坏了堆的结构，需要重新更新堆结构。
所以对于被置为deleted的时间节点，会延迟到它(1)超时 或
(2)它前面的节点都被删除时，它才会被删除。
一个点被置为deleted,它最迟会在TIMER_TIME_OUT时间后被删除。
这样做有两个好处：
(1) 第一个好处是不需要遍历优先队列，省时。
(2)
第二个好处是给超时时间一个容忍的时间，就是设定的超时时间是删除的下限(并不是一到超时时间就立即删除)，如果监听的请求在超时后的下一次请求中又一次出现了，
就不用再重新申请RequestData节点了，这样可以继续重复利用前面的RequestData，减少了一次delete和一次new的时间。
*/

#ifndef TIMER_H_
#define TIMER_H_

#include <unistd.h>
#include <deque>
#include <memory>
#include <queue>
#include "base/Mutex.h"
#include "base/noncopyable.h"

namespace san {

class HttpData;
class TimerNode {
public:
	TimerNode(std::shared_ptr<HttpData> requestData, int timeout);
	~TimerNode();
	TimerNode(TimerNode &tn);
	void update(int timeout);
	bool isValid();
	void clearReq();
	void setDeleted() { deleted_ = true; }
	bool isDeleted() const { return deleted_; }
	size_t getExpTime() const { return expiredTime_; }

private:
	bool deleted_;
	// ??? expiredTime_的含义是？
	size_t expiredTime_;
	std::shared_ptr<HttpData> httpDataPtr_;
};

class TimerCmp
{
public:
    bool operator()(std::shared_ptr<TimerNode> &a,
                    std::shared_ptr<TimerNode> &b) const
    {
      return a->getExpTime() > b->getExpTime();
    }
};

class TimerManager
{
public:
	TimerManager();
	~TimerManager();
	void addTimer(std::shared_ptr<HttpData> SPHttpData, int timeout);
	void handleExpiredEvent();

private:
	typedef std::shared_ptr<TimerNode> timerNodePtr_;

	// 使用优先级队列管理时钟
	std::priority_queue<timerNodePtr_, std::deque<timerNodePtr_>, TimerCmp>
	     timerNodeQueue_;
	// MutexLock lock;
};


} /* namespace san */

#endif /* TIMER_H_ */
